package com.itheima.service.mongo.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.itheima.domain.mongo.*;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.PageBeanVo;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;

@Service
public class MovementServiceImpl implements MovementService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdService idService;

    //保存动态
    @Override
    public void save(Movement movement) {

        //0.设置pid
        Long nextId = idService.getNextId(ConstantUtil.MOVEMENT_ID);
        movement.setPid(nextId);

        //1.1 向动态详情表中插入动态数据,获取动态id
        mongoTemplate.save(movement);
        //1.2 获取动态id
        ObjectId movementId = movement.getId();

        // =========================================

        //2. 向自己的动态表插入动态id
        //2.1 组装一个我的动态对象
        MyMovement myMovement = new MyMovement();
        myMovement.setPublishId(movementId);
        //这个应该是用前面动态表的created时间吧(我觉得不应该在写一个System.currentTimeMillis())
        myMovement.setCreated(movement.getCreated());
        //2.2 保存我的动态(写入 movement_mine_xx(xx取值：userId) 表中)
        mongoTemplate.save(myMovement, ConstantUtil.MOVEMENT_MINE + movement.getUserId());

        //==========================================

        //3. 通过朋友关系表(friend)查询出自己所有的朋友
        //3.1 写查询条件根据userId查询friendId
        Query query = new Query(Criteria.where("userId").is(movement.getUserId()));
        //3.2 查询到我的所有好友
        List<Friend> friends = mongoTemplate.find(query, Friend.class);

        //==========================================
        //4.向每个朋友的好友表(movement_friend_xx)表插入动态id(movementId)和发布人id（movement.getUserId()）
        //4.1先判断好友List中是否为空,不为空再进行插入动作
        if(CollectionUtil.isNotEmpty(friends)){
            for (Friend friend : friends) {

                Long friendId = friend.getFriendId();
                System.out.println(friendId);
                //4.2组装一个friendMovement对象，并向movemen_friend_xx表插入
                FriendMovement friendMovement = new FriendMovement();
                friendMovement.setPublishId(movementId);
                friendMovement.setUserId(movement.getUserId());
                friendMovement.setCreated(movement.getCreated());

                //4.3 保存到movement_friend_xx表中
                mongoTemplate.save(friendMovement,ConstantUtil.MOVEMENT_FRIEND+friendId);
            }
        }
    }


    //查询指定用户的动态信息
    @Override
    public PageBeanVo findMovementByUserId(Long userId, Integer pageNum, Integer pageSize) {

        //1. 从我的动态表中查询动态id集合
        Query query = new Query().with(Sort.by(Sort.Order.desc("created"))).skip((pageNum-1)*pageSize);

        List<MyMovement> myMovementList = mongoTemplate.find(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);

        //======================================================

        //2.遍历动态id集合，获取动态id
            //movementList存储动态详情集合
        List<Movement> movementList = new ArrayList<>();

        if(CollectionUtil.isNotEmpty(myMovementList)){

            for (MyMovement myMovement : myMovementList) {

                ObjectId movementId = myMovement.getPublishId();

                //3.根据动态id获取动态详情
                Movement movement = mongoTemplate.findById(movementId, Movement.class);

                //将动态存入动态集合movementList中
                //只有审核通过 state=1 才能存入
                if(movement.getState()==1){

                    movementList.add(movement);

                }
            }
        }
        //=====================================================

        //4.统计记录数
        long count = mongoTemplate.count(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);

        //5. 封装返回Vo
        return new PageBeanVo(pageNum,pageSize,count,movementList);
    }

    //查询指定用户的好友动态信息
    @Override
    public PageBeanVo findFriendMovementByUserId(Long userId, Integer pageNum, Integer pageSize) {
        //1. 查询我的好友动态表,获取到动态id
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .skip((pageNum - 1) * pageSize).limit(pageSize);
        List<FriendMovement> friendMovementList = mongoTemplate.find(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);

        //2. 遍历动态id集合,获取到动态id
        ArrayList<Movement> movementList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(friendMovementList)) {
            for (FriendMovement friendMovement : friendMovementList) {
                ObjectId movementId = friendMovement.getPublishId();

                //3. 根据动态id查询动态详情
                Movement movement = mongoTemplate.findById(movementId, Movement.class);

                //只有状态审核通过的,才能返回
                if (movement.getState() == 1) {
                    movementList.add(movement);
                }
            }
        }

        //4. 统计总记录数
        long count = mongoTemplate.count(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);

        //5. 封装返回vo
        return new PageBeanVo(pageNum, pageSize, count, movementList);
    }

    //查询指定用户的推荐动态信息
    @Override
    public PageBeanVo findRecommendMovement(Long userId, Integer pageNum, Integer pageSize) {
        //1.根据userId分页查询推荐给我的动态id集合
        Query query = new Query(
                Criteria.where("userId").is(userId))
                .with(Sort.by(Sort.Order.desc("score"), Sort.Order.desc("created")))
                .skip((pageNum-1)*pageSize).limit(pageSize);
        List<RecommendMovement> recommendMovementList = mongoTemplate.find(query, RecommendMovement.class);

        //2.遍历集合得到每个动态id
        List<Movement> movementList = new ArrayList<>();
        //先判断  推荐动态集合是否为空
        if(CollectionUtil.isNotEmpty(recommendMovementList)){
            for (RecommendMovement recommendMovement : recommendMovementList) {
                ObjectId movementId = recommendMovement.getPublishId();
                //3.根据动态Id查询动态详情
                Movement movement = mongoTemplate.findById(movementId, Movement.class);

                //把给个动态详情存入list(审核通过才能存入)
                if(movement.getState()==1){
                    movementList.add(movement);
                }
            }
        }

        //4.统计记录条数
        long count = mongoTemplate.count(query, RecommendMovement.class);

        //5.封装返回Vo
        return new PageBeanVo(pageSize,pageNum,count,movementList);
    }

    //根据动态id查询动态详情(单个动态)
    @Override
    public Movement findMovementById(String movementId) {
        return mongoTemplate.findById(movementId,Movement.class);
    }

    //根据用户的id和动态的状态查询
    @Override
    public PageBeanVo findUserMovementList(Long uid, Integer stateInt, Integer pageNum, Integer pageSize) {
        //1. 构建查询条件
        Query query = new Query().with(Sort.by(Sort.Order.desc("created"))).skip((pageNum - 1) * pageSize).limit(pageSize);
        if (uid != null) {
            query.addCriteria(Criteria.where("userId").is(uid));
        }
        if (stateInt != null) {
            query.addCriteria(Criteria.where("state").is(stateInt));
        }

        //2. 查询
        List<Movement> movementList = mongoTemplate.find(query, Movement.class);

        //3. 统计
        long count = mongoTemplate.count(query, Movement.class);

        //4. 返回
        return new PageBeanVo(pageNum, pageSize, count, movementList);
    }

    //根据审核过没过存储动态
    @Override
    public void updateMovement(Movement movement) {
        mongoTemplate.save(movement);
    }
}
